package com.hao.tool.web.module.fileInfo.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.ftp.Ftp;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hao.tool.extra.cloud.module.ali.AliCloudManager;
import com.hao.tool.extra.cloud.module.ali.entity.AlCosResult;
import com.hao.tool.extra.cloud.module.tengxun.TenCloudManager;
import com.hao.tool.extra.cloud.module.tengxun.entity.TxCosResult;
import com.hao.tool.web.common.constant.LayPage;
import com.hao.tool.web.component.properties.FTPProjectProperties;
import com.hao.tool.web.component.properties.PropertiesInfo;
import com.hao.tool.common.enums.StorageTypeEnum;
import com.hao.tool.web.module.fileInfo.controller.ImageRestController;
import com.hao.tool.web.module.fileInfo.entity.FileInfo;
import com.hao.tool.web.module.fileInfo.mapper.FileInfoMapper;
import com.hao.tool.web.module.fileInfo.service.FileInfoService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * description
 *
 * @author RuiHaoZ on GZ.cmhk
 * @date 2019-11-22 21:45
 */
@Service
public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {
    @Autowired
    private FileInfoMapper fileInfoMapper;
    @Autowired
    private FTPProjectProperties ftpProperties;
    @Autowired
    private PropertiesInfo propertiesInfo;

    @Override
    public LayPage<FileInfo> pageByInfo(LayPage<FileInfo> page, FileInfo fileInfo) {
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(fileInfo.getFileName()), "FILE_NAME", fileInfo.getFileName());
        queryWrapper.like(StringUtils.isNotBlank(fileInfo.getTagGroup()), "TAG_GROUP", fileInfo.getTagGroup());

        IPage<FileInfo> infoPage = this.page(page, queryWrapper);
        return (LayPage<FileInfo>) infoPage;
    }

    @Override
    public FileInfo uploadAndSaveFile(MultipartFile file, String userName, String storageType) throws IOException {
        InputStream inputStream = file.getInputStream();
        FileInfo fileInfo = new FileInfo();
        fileInfo.setId(IdWorker.getIdStr());
        String fileName = StringUtils.isNotBlank(file.getOriginalFilename())
                ? file.getOriginalFilename() : System.currentTimeMillis() + ".0";
        String fileType = FileUtil.extName(fileName).toLowerCase();

        String fileMd5 = "";
        String savePath = "";
        String tFileDir = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN) + "/" + fileType + "/";

        if (StorageTypeEnum.FTP.getCode().equalsIgnoreCase(storageType)) {
            Ftp ftp = new Ftp(ftpProperties.getFtpIp(), ftpProperties.getFtpPort(),
                    ftpProperties.getFtpUsername(), ftpProperties.getFtpPassword());
            savePath = ftpProperties.getBaseRootDir() + "fileInfo/";
            ftp.upload(savePath, file.getOriginalFilename(), inputStream);
            fileMd5 = DigestUtils.md5Hex(inputStream);
            fileInfo.setFilePath(savePath + file.getOriginalFilename());
        } else if (StorageTypeEnum.LOCAL.getCode().equalsIgnoreCase(storageType)) {
            savePath = propertiesInfo.getLocalFileRootDir() + File.separator + "fileInfo" + File.separator + fileName;
            FileUtil.writeFromStream(inputStream, new File(savePath));
            String accessUrl = ImageRestController.SEE_PATH.replace("{id}", fileInfo.getId());
            fileInfo.setAccessUrl(accessUrl);
            fileInfo.setFilePath(savePath);
            //fileMd5的位置不能放错，否则会导致流已被消耗
            fileMd5 = DigestUtils.md5Hex(inputStream);
        } else if (StorageTypeEnum.AL_COS.getCode().equalsIgnoreCase(storageType)) {
            savePath = "hao-tool/" + tFileDir;
            AlCosResult cosResult = AliCloudManager.buildCos(null, null)
                    .updateFile(savePath, fileName, inputStream);
            fileInfo.setAccessUrl(cosResult.getAccessUrl());
            fileInfo.setFilePath(savePath + fileName);

        } else if (StorageTypeEnum.TX_COS.getCode().equalsIgnoreCase(storageType)) {
            savePath = "hao-tool/" + tFileDir;
            TxCosResult cosResult = TenCloudManager.buildCos(null, null)
                    .upload(inputStream, savePath, fileName);
            fileInfo.setAccessUrl(cosResult.getAccessUrl());
            fileInfo.setFilePath(savePath + fileName);
        }
        Long fileSize = file.getSize();
        fileInfo.setFileMd5(fileMd5);
        fileInfo.setStorageType(storageType);
        fileInfo.setFileName(fileName);
        fileInfo.setFileType(fileType);
        fileInfo.setCreateTime(LocalDateTime.now());
        fileInfo.setCreateUser(userName);
        fileInfo.setClickCount(0L);
        fileInfo.setFileSize(fileSize);

        this.save(fileInfo);
        return fileInfo;
    }

    @Override
    public String fineMaxId() {
        FileInfo fileInfo = fileInfoMapper.selectLastInfo();
        if (fileInfo == null) {
            return "0";
        } else {
            return fileInfo.getId();
        }
    }
}
